﻿using AutoMapper;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.JsonPatch;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.AspNetCore.Mvc.Routing;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using TransformerManager.Shared.Helper;
using TransformerManager.API.Utils;
using TransformerManager.Shared.Dto.Accessories;
using TransformerManager.Shared.Dto.ActivePart;
using TransformerManager.Shared.Dto.BasicInfos;
using TransformerManager.Shared.Dto.Conservator;
using TransformerManager.Shared.Dto.CoolEquComp;
using TransformerManager.Shared.Dto.Lead;
using TransformerManager.Shared.Dto.Tank;
using TransformerManager.Shared.Dto.Transformer;
using TransformerManager.Shared.Dto.Winding;
using TransformerManager.EF.Models;
using TransformerManager.Shared.ResourceParameters;
using TransformerManager.Shared.Servers;
using TransformerManager.Shared.Helper.HttpParams;
using TransformerManager.Shared.Dto;

namespace TransformerManager.API.Controllers
{

    [ApiVersion("1.0")]
    [Route("api/v{version:apiVersion}/[controller]")]
    [ApiController]
    public class TransformersController : ControllerBase
    {
        private readonly ITransformerRepository _transformerRepository;
        private readonly IMapper _mapper;
        private readonly IUrlHelper _urlHelper;

        public TransformersController(
            ITransformerRepository transformerRepository,
            IMapper mapper,
            IUrlHelperFactory urlHelperFactory,
            IActionContextAccessor actionContextAccessor)
        {
            _transformerRepository = transformerRepository;
            _mapper = mapper;
            _urlHelper = urlHelperFactory.GetUrlHelper(actionContextAccessor.ActionContext);
        }


        /// <summary>
        /// 根据产品区域计算数量
        /// </summary>
        /// <param name="regionType">产品区域</param>
        /// <param name="from">起始时间</param>
        /// <param name="end">截止时间</param>
        /// <returns></returns>
        [HttpGet("Number")]
        public async Task<ActionResult<ServiceResponse<int>>> GetTransformersNumByRegion(
            [FromQuery] string regionType,
            [FromQuery] DateTime from,
            [FromQuery] DateTime end)
        {
            var response = new ServiceResponse<int>()
            {
                Data = 0
            };

            try
            {
                response.Data = await _transformerRepository.GetTransformersNumAsync(regionType, from, end);
            }
            catch(Exception e)
            {
                response.Message = e.Message;
                response.Success = false;
                return BadRequest(response);
            }
            return Ok(response);
        }

        /// <summary>
        /// 按检索要求获取指定数量的变压器列表
        /// </summary>
        /// <param name="trResourceParams">检索参数</param>
        /// <param name="paginationParams">分页参数</param>
        /// <returns></returns>
        [Authorize(AuthenticationSchemes = "Bearer")]
        [HttpPost("Query", Name = "GetTransformers")]
        [HttpHead]
        public async Task<ActionResult<ServiceResponse<IEnumerable<TransformerDto>>>> GetTransformers(
            [FromBody] TransformerResourceParameters trResourceParams,
            [FromQuery] PaginationResourceParameters paginationParams)
        {
            var transformersFromRepo = await _transformerRepository.GetTransformersAsync(
                trResourceParams, paginationParams);
            var response = new ServiceResponse<IEnumerable<TransformerDto>>();

            if (transformersFromRepo == null || transformersFromRepo.Count() <= 0)
            {
                response.Message = "没有检索到变压器信息";
                response.Success = false;
                return NotFound(response);
            }

            var transformersDto = _mapper.Map<IEnumerable<TransformerDto>>(transformersFromRepo);

            // 生成前一页的URL
            var previousPageLink = transformersFromRepo.HasPrevious ?
                HttpUtils.GenerateRouteResourceURL(
                    paginationParams,
                    "GetTransformers",
                    ResourceUrlType.PreviousPage,
                    _urlHelper) : null;

            // 生成后一页的URL
            var nextPageLink = transformersFromRepo.HasNext ?
                HttpUtils.GenerateRouteResourceURL(
                    paginationParams,
                    "GetTransformers",
                    ResourceUrlType.NextPage,
                    _urlHelper) : null;

            var paginationMetadata = new
            {
                previousPageLink,
                nextPageLink,
                totalCount = transformersFromRepo.TotalCount,
                pageSize = transformersFromRepo.PageSize,
                currentPage = transformersFromRepo.CurrentPage,
                totalPages = transformersFromRepo.TotalPages
            };

            // 通过Response的头部信息返回hatos成熟度3等级的restful头信息
            Response.Headers.Add("x-pagination",
                Newtonsoft.Json.JsonConvert.SerializeObject(paginationMetadata));

            response.Data = transformersDto;
            return Ok(response);
        }

        /// <summary>
        /// 通过GUID查询数据
        /// </summary>
        /// <param name="transformerId">变压器的GUID</param>
        /// <returns></returns>
        [HttpGet("{transformerId:Guid}", Name = "GetTransformerFromId")]
        public async Task<ActionResult<ServiceResponse<TransformerDto>>> GetTransformerFromId(Guid transformerId)
        {
            var transformerFromRepo = await _transformerRepository.GetTransformerAsync(transformerId);
            var response = new ServiceResponse<TransformerDto>();

            if (transformerFromRepo == null)
            {
                response.Message = $"{transformerId} 变压器找不到";
                response.Success = false;
                return NotFound(response);
            }

            var transformerDto = _mapper.Map<TransformerDto>(transformerFromRepo);
            response.Data = transformerDto;

            return Ok(response);
        }

        /// <summary>
        /// 核查项目号是有效
        /// </summary>
        /// <param name="projectNumber">项目号</param>
        /// <returns></returns>
        [HttpGet("{projectNumber}")]
        public async Task<ActionResult<ServiceResponse<bool>>> CheckTransformerProjectValid(string projectNumber)
        {
            var response = new ServiceResponse<bool>() { Data = false };
            if (!await _transformerRepository.CheckTransformerExistByProjectNumberAsync(projectNumber))
            {
                response.Data = true;
                return Ok(response);
            }

            response.Data = false;
            response.Message = $"项目号: {projectNumber}已存在";
            return Conflict(response);
        }

        /// <summary>
        /// 创建变压器数据
        /// </summary>
        /// <param name="transformerForCreationDto">创建产品参数</param>
        /// <returns></returns>
        [Authorize(AuthenticationSchemes = "Bearer")]
        [HttpPost]
        public async Task<ActionResult<ServiceResponse<TransformerDto>>> CreateTransformer([FromBody] TransformerForCreationDto transformerForCreationDto)
        {
            string projectNumber = transformerForCreationDto.BasicInfos.ProjectNumber;
            var response = new ServiceResponse<TransformerDto>();

            var transformerModel = _mapper.Map<TransformerForCreationDto, Transformer>(transformerForCreationDto);

            _transformerRepository.AddTransformer(transformerModel);
            bool success = await _transformerRepository.SaveChangesAsync();
            if (!success)
            {
                response.Success = false;
                response.Message = $"创建项目 V{projectNumber}失败";
                return BadRequest(response);
            }

            var transformerDto = _mapper.Map<TransformerDto>(transformerModel);

            response.Data = transformerDto;
            response.Message = $"创建项目 V{projectNumber}成功";
            return Created(
                "GetTransformerFromId",
                response);
        }

        #region 更新数据

        /// <summary>
        /// 更新变压器所有数据
        /// </summary>
        /// <param name="transformerId">变压器的GUID</param>
        /// <param name="transformerForUpdateDto">完整的更新参数</param>
        /// <returns></returns>
        [Authorize(AuthenticationSchemes = "Bearer")]
        [HttpPut("{transformerId}")]
        public async Task<ActionResult<ServiceResponse<TransformerDto>>> UpdateTransformerParams(
            [FromRoute] Guid transformerId,
            [FromBody] TransformerForUpdateDto transformerForUpdateDto)
        {
            string projectNumber = transformerForUpdateDto.BasicInfos.ProjectNumber;
            var response = new ServiceResponse<TransformerDto>();

            if (!await _transformerRepository.CheckTransformerExistAsync(transformerId))
            {
                response.Message = $"当前V{projectNumber}的变压器找不到";
                response.Success = false;
                return NotFound(response);
            }

            var transformerModel = await _transformerRepository.GetTransformerAsync(transformerId);

            _mapper.Map(transformerForUpdateDto, transformerModel);
            bool success = await _transformerRepository.SaveChangesAsync();

            if (!success)
            {
                response.Message = $"V{projectNumber}数据更新失败!";
                response.Success = false;
                return BadRequest(response);
            }

            response.Message = $"更新V{projectNumber}数据成功!";
            response.Data = _mapper.Map<TransformerDto>(transformerModel);
            return Ok(response);
        }

        /// <summary>
        /// 更新变压器的基本数据
        /// </summary>
        /// <param name="transformerId">变压器的GUID</param>
        /// <param name="basicInfosForUpdateDto">需要更新的基本数据</param>
        /// <returns></returns>
        [Authorize(AuthenticationSchemes = "Bearer")]
        [HttpPut("BasicInfos/{transformerId}")]
        public async Task<ActionResult<ServiceResponse<BasicInfosDto>>> UpdateBasicInfosParams(
            [FromRoute] Guid transformerId,
            [FromBody] BasicInfosForUpdateDto basicInfosForUpdateDto)
        {
            var response = new ServiceResponse<BasicInfosDto>();

            if (!await _transformerRepository.CheckTransformerExistAsync(transformerId))
            {
                response.Message = $"当前Id={transformerId}的变压器找不到";
                response.Success = false;
                return NotFound(response);
            }

            var basicInfosModel = await _transformerRepository.GetBasicInfosAsync(transformerId);

            _mapper.Map(basicInfosForUpdateDto, basicInfosModel);
            bool success = await _transformerRepository.SaveChangesAsync();

            if (!success)
            {
                response.Message = $"Id={transformerId}的数据更新失败!";
                response.Success = false;
                return BadRequest(response);
            }

            response.Message = $"Id={transformerId}的数据更新成功!";
            response.Data = _mapper.Map<BasicInfosDto>(basicInfosModel);
            return Ok(response);
        }

        /// <summary>
        /// 更新变压器的油箱所有数据
        /// </summary>
        /// <param name="transformerId">变压器的GUID</param>
        /// <param name="tankForUpdateDto">油箱的更新数据</param>
        /// <returns></returns>
        [Authorize(AuthenticationSchemes = "Bearer")]
        [HttpPut("Tank/{transformerId}")]
        public async Task<ActionResult<ServiceResponse<TankDto>>> UpdateTankParams(
            [FromRoute] Guid transformerId,
            [FromBody] TankForUpdateDto tankForUpdateDto)
        {
            var response = new ServiceResponse<TankDto>();

            if (!await _transformerRepository.CheckTransformerExistAsync(transformerId))
            {
                response.Message = $"当前Id={transformerId}的变压器找不到";
                response.Success = false;
                return NotFound(response);
            }

            var tankModel = await _transformerRepository.GetTankAsync(transformerId);

            _mapper.Map(tankForUpdateDto, tankModel);
            bool success = await _transformerRepository.SaveChangesAsync();

            if (!success)
            {
                response.Message = $"Id={transformerId}的数据更新失败!";
                response.Success = false;
                return BadRequest(response);
            }

            response.Message = $"Id={transformerId}的数据更新成功!";
            response.Data = _mapper.Map<TankDto>(tankModel);
            return Ok(response);
        }

        /// <summary>
        /// 更新储油柜的所有数据
        /// </summary>
        /// <param name="transformerId">变压器的GUID</param>
        /// <param name="conservatorForUpdateDto">储油柜的更新数据</param>
        /// <returns></returns>
        [Authorize(AuthenticationSchemes = "Bearer")]
        [HttpPut("Conservator/{transformerId}")]
        public async Task<ActionResult<ServiceResponse<ConservatorDto>>> UpdateConservatorParams(
            [FromRoute] Guid transformerId,
            [FromBody] ConservatorForUpdateDto conservatorForUpdateDto)
        {
            var response = new ServiceResponse<ConservatorDto>();

            if (!await _transformerRepository.CheckTransformerExistAsync(transformerId))
            {
                response.Message = $"当前Id={transformerId}的变压器找不到";
                response.Success = false;
                return NotFound(response);
            }

            var conservatorModel = await _transformerRepository.GetConservatorAsync(transformerId);

            _mapper.Map(conservatorForUpdateDto, conservatorModel);
            bool success = await _transformerRepository.SaveChangesAsync();

            if (!success)
            {
                response.Message = $"Id={transformerId}的数据更新失败!";
                response.Success = false;
                return BadRequest(response);
            }

            response.Message = $"Id={transformerId}的数据更新成功!";
            response.Data = _mapper.Map<ConservatorDto>(conservatorModel);
            return Ok(response);
        }

        /// <summary>
        /// 更新冷却系统的所有数据
        /// </summary>
        /// <param name="transformerId">变压器的GUID</param>
        /// <param name="coolingSystemForUpdateDto">冷却系统的更新数据</param>
        /// <returns></returns>
        [Authorize(AuthenticationSchemes = "Bearer")]
        [HttpPut("CoolingSystem/{transformerId}")]
        public async Task<ActionResult<ServiceResponse<CoolingSystemDto>>> UpdateCoolingSystemParams(
            [FromRoute] Guid transformerId,
            [FromBody] CoolingSystemForUpdateDto coolingSystemForUpdateDto)
        {
            var response = new ServiceResponse<CoolingSystemDto>();

            if (!await _transformerRepository.CheckTransformerExistAsync(transformerId))
            {
                response.Message = $"当前Id={transformerId}的变压器找不到";
                response.Success = false;
                return NotFound(response);
            }

            var coolingSystemModel = await _transformerRepository.GetCoolingSystemAsync(transformerId);

            _mapper.Map(coolingSystemForUpdateDto, coolingSystemModel);
            bool success = await _transformerRepository.SaveChangesAsync();

            if (!success)
            {
                response.Message = $"Id={transformerId}的数据更新失败!";
                response.Success = false;
                return BadRequest(response);
            }

            response.Message = $"Id={transformerId}的数据更新成功!";
            response.Data = _mapper.Map<CoolingSystemDto>(coolingSystemModel);
            return Ok(response);
        }

        /// <summary>
        /// 更新附件的所有数据
        /// </summary>
        /// <param name="transformerId">变压器的GUID</param>
        /// <param name="accessoriesForUpdateDto">附件的更新数据</param>
        /// <returns></returns>
        [Authorize(AuthenticationSchemes = "Bearer")]
        [HttpPut("Accessories/{transformerId}")]
        public async Task<ActionResult<ServiceResponse<AccessoriesDto>>> UpdateAccessoriesParams(
            [FromRoute] Guid transformerId,
            [FromBody] AccessoriesForUpdateDto accessoriesForUpdateDto)
        {
            var response = new ServiceResponse<AccessoriesDto>();

            if (!await _transformerRepository.CheckTransformerExistAsync(transformerId))
            {
                response.Message = $"当前Id={transformerId}的变压器找不到";
                response.Success = false;
                return NotFound(response);
            }

            var accessoriesModel = await _transformerRepository.GetAccessoriesAsync(transformerId);

            _mapper.Map(accessoriesForUpdateDto, accessoriesModel);
            bool success = await _transformerRepository.SaveChangesAsync();

            if (!success)
            {
                response.Message = $"Id={transformerId}的数据更新失败!";
                response.Success = false;
                return BadRequest(response);
            }

            response.Message = $"Id={transformerId}的数据更新成功!";
            response.Data = _mapper.Map<AccessoriesDto>(accessoriesModel);
            return Ok(response);
        }

        /// <summary>
        /// 更新引线的所有数据
        /// </summary>
        /// <param name="transformerId">变压器的GUID</param>
        /// <param name="leadForUpdateDto">引线的更新数据</param>
        /// <returns></returns>
        [Authorize(AuthenticationSchemes = "Bearer")]
        [HttpPut("Lead/{transformerId}")]
        public async Task<ActionResult<ServiceResponse<LeadDto>>> UpdateLeadParams(
            [FromRoute] Guid transformerId,
            [FromBody] LeadForUpdateDto leadForUpdateDto)
        {
            var response = new ServiceResponse<LeadDto>();

            if (!await _transformerRepository.CheckTransformerExistAsync(transformerId))
            {
                response.Message = $"当前Id={transformerId}的变压器找不到";
                response.Success = false;
                return NotFound(response);
            }

            var leadModel = await _transformerRepository.GetLeadAsync(transformerId);

            _mapper.Map(leadForUpdateDto, leadModel);
            bool success = await _transformerRepository.SaveChangesAsync();

            if (!success)
            {
                response.Message = $"Id={transformerId}的数据更新失败!";
                response.Success = false;
                return BadRequest(response);
            }

            response.Message = $"Id={transformerId}的数据更新成功!";
            response.Data = _mapper.Map<LeadDto>(leadModel);
            return Ok(response);
        }

        /// <summary>
        /// 更新线圈的所有数据
        /// </summary>
        /// <param name="transformerId">变压器的GUID</param>
        /// <param name="windingForUpdateDto">线圈的更新数据</param>
        /// <returns></returns>
        [Authorize(AuthenticationSchemes = "Bearer")]
        [HttpPut("Winding/{transformerId}")]
        public async Task<ActionResult<ServiceResponse<WindingDto>>> UpdateWindingParams(
            [FromRoute] Guid transformerId,
            [FromBody] WindingForUpdateDto windingForUpdateDto)
        {
            var response = new ServiceResponse<WindingDto>();

            if (!await _transformerRepository.CheckTransformerExistAsync(transformerId))
            {
                response.Message = $"当前Id={transformerId}的变压器找不到";
                response.Success = false;
                return NotFound(response);
            }

            var windingModel = await _transformerRepository.GetWindingAsync(transformerId);

            _mapper.Map(windingForUpdateDto, windingModel);
            bool success = await _transformerRepository.SaveChangesAsync();

            if (!success)
            {
                response.Message = $"Id={transformerId}的数据更新失败!";
                response.Success = false;
                return BadRequest(response);
            }

            response.Message = $"Id={transformerId}的数据更新成功!";
            response.Data = _mapper.Map<WindingDto>(windingModel);
            return Ok(response);
        }

        /// <summary>
        /// 更新器身的所有数据
        /// </summary>
        /// <param name="transformerId">变压器的GUID</param>
        /// <param name="activePartForUpdateDto">器身的更新数据</param>
        /// <returns></returns>
        [Authorize(AuthenticationSchemes = "Bearer")]
        [HttpPut("ActivePart/{transformerId}")]
        public async Task<ActionResult<ServiceResponse<ActivePartDto>>> UpdateActivePartParams(
            [FromRoute] Guid transformerId,
            [FromBody] ActivePartForUpdateDto activePartForUpdateDto)
        {
            var response = new ServiceResponse<ActivePartDto>();

            if (!await _transformerRepository.CheckTransformerExistAsync(transformerId))
            {
                response.Message = $"当前Id={transformerId}的变压器找不到";
                response.Success = false;
                return NotFound(response);
            }

            var activePartModel = await _transformerRepository.GetActivePartAsync(transformerId);

            _mapper.Map(activePartForUpdateDto, activePartModel);
            bool success = await _transformerRepository.SaveChangesAsync();

            if (!success)
            {
                response.Message = $"Id={transformerId}的数据更新失败!";
                response.Success = false;
                return BadRequest(response);
            }

            response.Message = $"Id={transformerId}的数据更新成功!";
            response.Data = _mapper.Map<ActivePartDto>(activePartModel);
            return Ok(response);
        }

        /// <summary>
        /// 部分参数更新
        /// </summary>
        /// <param name="transformerId">变压器的GUID</param>
        /// <param name="patchDocument">部分更新的参数</param>
        /// <returns></returns>
        [Authorize(AuthenticationSchemes = "Bearer")]
        [HttpPatch("{transformerId}")]
        public async Task<ActionResult<ServiceResponse>> PartiallyUpdateTransformer(
             [FromRoute] Guid transformerId,
            [FromBody] JsonPatchDocument<TransformerForUpdateDto> patchDocument)
        {
            var response = new ServiceResponse();

            if (!await _transformerRepository.CheckTransformerExistAsync(transformerId))
            {
                response.Message = $"当前Id={transformerId}的变压器找不到";
                response.Success = false;
                return NotFound(response);
            }

            var transformerFromRepo = await _transformerRepository.GetTransformerAsync(transformerId);

            var transformerForPatchDto = _mapper.Map<TransformerForUpdateDto>(transformerFromRepo);

            patchDocument.ApplyTo(transformerForPatchDto, ModelState);

            if (!TryValidateModel(transformerForPatchDto))
            {
                return ValidationProblem(ModelState);
            }

            _mapper.Map(transformerForPatchDto, transformerFromRepo);
            bool success = await _transformerRepository.SaveChangesAsync();

            if (!success)
            {
                response.Message = $"Id={transformerId}的数据更新失败!";
                response.Success = false;
                return BadRequest(response);
            }

            response.Message = $"Id={transformerId}的变压器数据更新成功!";
            return Ok(response);
        }

        #endregion

        /// <summary>
        /// 从数据库中删除指定GUID的变压器信息
        /// </summary>
        /// <param name="transformerId"></param>
        /// <returns></returns>
        [Authorize(Roles = "Admin, SuperAdmin")]
        [Authorize(AuthenticationSchemes = "Bearer")]
        [HttpDelete("{transformerId}")]
        public async Task<ActionResult<ServiceResponse>> DeleteTransformer(
            [FromRoute] Guid transformerId)
        {
            var response = new ServiceResponse();

            if (!await _transformerRepository.CheckTransformerExistAsync(transformerId))
            {
                response.Message = $"当前Id={transformerId}的变压器找不到";
                response.Success = false;
                return NotFound(response);
            }

            var transformerFromRepo = _transformerRepository.GetTransformerAsync(transformerId);

            string projectNumber = transformerFromRepo.Result.BasicInfos.ProjectNumber;

            _transformerRepository.DeleteTransformer(transformerFromRepo.Result);

            bool success = await _transformerRepository.SaveChangesAsync();
            if (!success)
            {
                response.Message = $"Id={transformerId}的数据更新失败!";
                response.Success = false;
                return BadRequest(response);
            }

            response.Message = $"成功删除V{projectNumber}的数据!";
            return Ok(response);
        }


        /// <summary>
        /// 根据产品GUID批量删除变压器信息
        /// </summary>
        /// <param name="ids">变压器的GUID</param>
        /// <returns></returns>
        [Authorize(Roles = "Admin, SuperAdmin")]
        [Authorize(AuthenticationSchemes = "Bearer")] //jwt的身份验证，必须显示添加bearer方式验证
        [HttpDelete]
        public async Task<ActionResult<ServiceResponse>> DeleteTransformers([FromQuery] string ids)
        {
            string[] idArray = ids.Split(",");
            List<Guid> guids = new List<Guid>();
            foreach (var id in idArray)
            {
                guids.Add(Guid.Parse(id));
            }
            IEnumerable<Guid> transformerGuids = guids.AsEnumerable<Guid>();

            IEnumerable<Transformer> transformersFromRepo = await _transformerRepository.GetTransformerByIdsAsync(transformerGuids);

            var response = new ServiceResponse();

            if (transformersFromRepo == null || transformersFromRepo.Count() == 0)
            {
                response.Message = "批量删除变压器数据失败!";
                response.Success = false;
                return BadRequest(response);
            }

            _transformerRepository.DeleteTransformers(transformersFromRepo);
            bool success = await _transformerRepository.SaveChangesAsync();

            if (!success)
            {
                response.Message = "批量删除变压器数据失败!";
                response.Success = false;
                return BadRequest(response);
            }

            response.Message = $"成功批量删除Id为 {ids} 的变压器数据。";
            return Ok(response);

        }
    }
}
